package com.yunao.commons.metasearch.ms;

import com.yunao.commons.metasearch.common.Convert;
import com.yunao.commons.metasearch.common.HttpRequest;
import com.yunao.commons.metasearch.common.HttpResponse;
import com.yunao.commons.metasearch.common.StringUtil;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Jsoup 连接 url 解析 html
 * 
 * @author glt
 * 
 */
public class JsoupUtil {

	// 伪装火狐浏览器
	private static final String USERAGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36";

	// 超时连接时间6秒
	private static final int TIMEOUT = 6000;

	/**
	 * 连接
	 */
	public static Document conn(String url) {
		if (url == null || url.length() == 0)
			return null;
		Document doc = null;
//		Map<String,String> map = new HashMap<String,String>();
//		String cookie = "ww_sTitle=12306*%E6%88%91; CXID=3E2F52FC1B1C956A64ED86459842404C; SUV=1490261629694267; ssuid=9567856990; sw_uuid=8728185958; sg_uuid=9031498268; pgv_pvi=6997366784; _ga=GA1.2.559777949.1490261636; wuid=AAEEtqhfGAAAAAqLEm9HzwMAGwY=; ad=siRNnkllll2Bl9SalllllV6GplDllllllbFypyllll9lllllxv7ll5@@@@@@@@@@; SUID=19D0B4013765860A58CF8318000975A9; sct=25; SNUID=012F2E7D0D085C213C88ACC70D94FD27; usid=2DD0B4014F0A900A000000005923E8F7; dt_ssuid=7928586704; IPLOC=CN1100; ld=Qlllllllll2BwM0TlllllV66cj6llllltjGARlllll9lllllpllll5@@@@@@@@@@";
//		 String[] cookiess=cookie.split("; ");
//
//		for(int  j=0;j<cookiess.length;j++)
//					{
//			try{
//			map.put(cookiess[j].split("=")[0],cookiess[j].split("=")[1]);
//
//
//				}catch(Exception e)
//				{
//					e.printStackTrace();
//
//				}
//
//
//			}
		Map<String,String> headers = new HashMap<>();
		headers.put("Accept-Encoding", "gzip");
		try {
			doc = Jsoup.connect(url).userAgent(USERAGENT).timeout(TIMEOUT).header("Accept-Encoding", "gzip").get();
			if (doc != null) {
				Elements as = doc.select("a");
				for (Element a : as) {
					a.attr("href", a.absUrl("href"));
					a.attr("target", "_blank");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return doc;
	}
	
	public static void main(String[] args) throws IOException {
		String url = "http://www.so.com/s?q=北京";
		Document doc = Jsoup.connect(url).userAgent(USERAGENT).get();
		System.out.println(doc);
	}

	/**
	 * 连接
	 */
	public static Document conn(String url, Map<String, String> cookie) {
		if (url == null || url.length() == 0)
			return null;
		if (cookie == null)
		{
			return conn(url);
		}
		Document doc = null;
		try {
			doc = Jsoup.connect(url).userAgent(USERAGENT).cookies(cookie).timeout(TIMEOUT).get();
			if (doc != null) {
				Elements as = doc.select("a");
				for (Element a : as) {
					a.attr("href", a.absUrl("href"));
					a.attr("target", "_blank");
				}
			}
		} catch (Exception e) {

		}
		return doc;
	}
	public static Document conn(String url, String cookie,String refer) {
		
		if (url == null || url.length() == 0)
			return null;
		Document doc = null;
		try{
			HttpRequest request = new HttpRequest();
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String> headers = new HashMap<String, String>();

			headers.put("Accept-Encoding", "gzip"); //使用gzip压缩传输数据让访问更快
			headers.put("user-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36");
			if(cookie!=null){
				headers.put("cookie",cookie);
			}
			if(refer!=null){
				headers.put("refer",refer);
			}
			HttpResponse response = request.sendGet(url, params, headers, null);

			String content = response.getContent();
			if (content != null) {
				doc = Jsoup.parse(content);
				Elements as = doc.select("a");
				for (Element a : as) {
					a.attr("href", a.absUrl("href"));
					a.attr("target", "_blank");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return doc;
	}
	/**
	 * 响应
	 */
	public static Response response(String url) {
		if (url == null || url.length() == 0)
			return null;
		Response response = null;
		try {
			response = Jsoup.connect(url).userAgent(USERAGENT).timeout(TIMEOUT).execute();
		} catch (Exception e) {

		}
		return response;
	}

	/**
	 * 响应
	 */
	public static Response response(String url, Map<String, String> cookies) {
		if (url == null || url.length() == 0)
			return null;
		if (cookies == null)
			return response(url);
		Response response = null;
		try {
			response = Jsoup.connect(url).userAgent(USERAGENT).cookies(cookies).timeout(TIMEOUT).execute();
		} catch (Exception e) {

		}
		return response;
	}
	
	
	
	/**
	 * 完整的节点 html 内容
	 */
	public String outhtml(Element e, String tag) {
		if (tag.indexOf("+") != -1) {
			String[] subTags = Convert.split(tag, "+");
			String html = "";
			for (String subTag : subTags) {
				html += html(e, subTag);
			}
			return html;
		}
		e = parse(e, tag);
		if (e == null)
			return "";
		return e.outerHtml();
	}
	
	
	
	
	
	
	
	
	
	
	

	/**
	 * 节点 html 内容
	 */
	public String html(Element e, String tag) {
		if (tag.indexOf("+") != -1) {
			String[] subTags = Convert.split(tag, "+");
			String html = "";
			for (String subTag : subTags) {
				html += html(e, subTag);
			}
			return html;
		}
		e = parse(e, tag);
		//System.out.println("title:"+e.html());
		if (e == null)
			return "";
		return e.html();
	}

	/**
	 * 节点内容
	 */
	public String text(Element e, String tag) {
		if (tag.indexOf("+") != -1) {
			String[] subTags = Convert.split(tag, "+");
			String text = "";
			for (String subTag : subTags) {
				text += text(e, subTag);
			}
			return text;
		}
		e = parse(e, tag);
		if (e == null)
			return "";
		if (tag.endsWith(")")) {
			tag = tag.substring(tag.lastIndexOf("(") + 1, tag.lastIndexOf(")"));
			if (tag.length() > 1 && Convert.getInt(tag) == 0)
				return e.attr(tag);
		}
		return e.text();
	}

	/**
	 * 解析 html
	 * @throws InterruptedException 
	 */
	public Elements list(Element e, String all, String items)  {
		Elements rs = null;
		if (items.indexOf("!") != -1) {
			rs = parsesNoSpaces(e, items.substring(items.indexOf("!") + 1));
			items = items.substring(0, items.indexOf("!"));
		}
		Elements allNodes = parses(e, all);
		if (allNodes == null || allNodes.size() == 0) {
			
			return null;
		} else if (allNodes.size() == 1) {
			Element node = allNodes.first();
			Elements elements = parses(node, items);
			Elements results = new Elements();
			for (Element element : elements) {
			
				//if (element.parent().equals(node)) {
					
				
					
					boolean flag = true;
					if (rs != null) {
						for (Element r : rs) {
							if (element.equals(r))
								flag = false;
						}
					}
					if (flag)
						results.add(element);
				//}
			}
			return results;
		} else {
			Elements list = new Elements();
			for (Element node : allNodes) {
				Elements elements = parses(node, items);
				Elements results = new Elements();
				for (Element element : elements) {
					if (element.parent().equals(node)) {
						boolean flag = true;
						if (rs != null) {
							for (Element r : rs) {
								if (element.equals(r))
									flag = false;
							}
						}
						if (flag)
							results.add(element);
					}
				}
				list.addAll(results);
			}
			return list;
		}
	}

	/**
	 * 结果
	 */
	public int result(Element e, String tag) {
		e = parse(e, tag);
		int num = 0;
		if(e!=null){
			String str= e.html();

			if(str.contains("共")){
				str=str.split("共")[1];
				String r = str;
				num = StringUtil.extractInt(r);
			}else{
				if (e != null) {
					String r = e.text();
					if (r.indexOf("用时") != -1)
						r = r.substring(0, r.indexOf("用时"));
					num = StringUtil.extractInt(r);
				}
			}
		}
		return num;
	}

	/**
	 * 解析节点
	 */
	public Element parse(Element e, String tag) {
		if (tag == null || tag.length() == 0)
			return null;
		if (tag.indexOf(" ") == -1)
			return parseNoSpaces(e, tag);
		String[] tags = Convert.split(tag, " ");
		for (String subTag : tags) {
			e = parseNoSpaces(e, subTag);
		}
		return e;
	}

	/**
	 * 解析节点
	 */
	public Elements parses(Element e, String tag) {
		if (tag == null || tag.length() == 0)
			return null;
		// 没有空格时
		if (tag.indexOf(" ") == -1)
			return parsesNoSpaces(e, tag);
		

		String[] tags = Convert.split(tag, " ");
		Elements elements = null;
		for (int i = 0; i < tags.length; i++) {
			if (i == tags.length - 1)
				// 最后一个节点
				elements = parsesNoSpaces(e, tags[i]);
			else
				e = getElement(e, tags[i]);
		}
		return elements;
	}

	/**
	 * 解析 html 获取节点
	 */
	private Element parseNoSpaces(Element e, String tag) {
		if (e == null || tag == null || tag.length() == 0)
			return null;
		// key 中含有排除项
		if (tag.indexOf("!") != -1) {
			e = parseNoSpaces(e, tag.substring(0, tag.indexOf("!")));
			remove(e, tag.substring(tag.indexOf("!") + 1));
			return e;
		}
		// 节点标示 id
		if (tag.indexOf("[id=") != -1)
			return e.getElementById(getAttrValue(tag));
		return getElement(e, tag);
	}

	/**
	 * 删除节点
	 */
	private void remove(Element e, String tag) {
		Elements elements = parses(e, tag);
		if (elements != null && elements.size() > 0)
			for (Element element : elements) {
				element.remove();
			}
	}

	/**
	 * 解析标签获取节点
	 */
	private Element getElement(Element e, String tag) {
		Elements elements = parsesNoSpaces(e, tag);
		// 没有内容
		if (elements == null || elements.size() == 0)
			return null;
		// 有且仅有一个节点时或标签没有中没有括号
		if (elements.size() == 1 || tag.indexOf("(") == -1)
			return elements.first();
		int index = Convert.getInt(tag.substring(tag.indexOf("(") + 1, tag.indexOf(")")));
		if (index == 0)
			return elements.first();
		// 括号内值为数字且合法时
		else if (elements.size() >= index)
			return elements.get(index - 1);
		return null;
	}

	/**
	 * 解析 html 获取节点集合
	 */
	private Elements parsesNoSpaces(Element n, String tag) {
		Element e = n;
		if (e == null || tag == null || tag.length() == 0)
			return null;
		Elements results = null;
		// 有多个属性时
		if (tag.indexOf("[") != -1 && tag.indexOf("[") != tag.indexOf("[")) {
			// 以第一个属性获取节点集合
			Elements subes = e.getElementsByAttributeValue(getAttrKey(tag), getAttrValue(tag));
			// 属性键值对
			Map<String, String> attrMap = new HashMap<String, String>();
			while (true) {
				tag = tag.substring(tag.indexOf("]") + 1);
				if (tag.length() == 0)
					break;
				attrMap.put(getAttrKey(tag), getAttrValue(tag));
			}
			results = new Elements();
			// 遍历以第一个属性获取节点集合
		
			for (Element sube : subes) {
				boolean flag = true;
				for (Map.Entry<String, String> attr : attrMap.entrySet()) {
					String key = attr.getKey();
					String value = attr.getValue();
					// 值为空或属性不同
					if (value == null || !value.equals(sube.attr(key))) {
						flag = false;
						break;
					}
				}
				if (flag)
					results.add(sube);
			

			}
		} else if (tag.indexOf("[class=") != -1) {
			// 单个属性，且属性为 class
	
			results = e.getElementsByClass(getAttrValue(tag));
	
		} else if (tag.indexOf("=") != -1) {
			// 单属性
			results = e.getElementsByAttributeValue(getAttrKey(tag), getAttrValue(tag));
		} else {
			// 以标签获取
			tag = tag.contains("(") ? tag.substring(0, tag.indexOf("(")) : tag;
			results = e.getElementsByTag(tag);
		}
		
		
		
		return results;
	}

	/**
	 * 获取标签键值对中的键
	 */
	private String getAttrKey(String tag) {
		return tag.substring(tag.indexOf("[") + 1, tag.indexOf("="));
	}

	/**
	 * 获取标签键值对中的值
	 */
	private String getAttrValue(String tag) {
		return tag.substring(tag.indexOf("=") + 1, tag.indexOf("]"));
	}
}
